﻿using DevExpress.XtraBars;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Container;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraTreeList;
using Inaction.UI.Common;
using System;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;

namespace Inaction.UI
{
    public partial class BarManager : ISupportInitialize
    {
        #region ISupportInitialize 成员
        FormManager formManager = null;
        public FormManager FormManager
        {
            get { return formManager; }
        }

        internal EditorContainer focusedEditorContainer = null;

        void System.ComponentModel.ISupportInitialize.EndInit()
        {
            base.EndInit();
            if (IsDesignMode) return;
            try
            {
                var f = GetForm();
                if (f == null) return;
                ShowWaitDialog("正在初始化窗口...");
                System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
                watch.Start();
                f.AutoValidate = System.Windows.Forms.AutoValidate.EnableAllowFocusChange;
                RegisteEvent();
                if (f is BaseForm) { (f as BaseForm).BarManager = this; }
                formManager = new FormManager(f, this);
                if (ShowSourceDetail == false)
                {
                    BarItemCurrentDetail.Visibility = BarItemVisibility.Never;
                }
                f.Load += (a, b) =>
                {
                    if (this.DesignMode) return;
                    InitExtenders();
                    if (f.Owner != null)
                    {
                        f.Icon = f.Owner.Icon;
                    }
                    InitBindingControls();
                    InitOnLoad();
                    if (MasterBindingInfo != null && MasterBindingInfo.SavableObj != null && MasterBindingInfo.SavableObj.IsDirty)
                    {
                        operateState = BarManagerState.Modify;
                    }
                    ApplyFormRules();
                };
                f.FormClosing += (s, e) =>
                {
                    if (EditMode && MasterBindingInfo != null && MasterBindingInfo.IsDirty)
                    {
                        if (MessageBox.Show("当前窗口处于编辑状态，关闭窗口会取消当前的操作！" + Environment.NewLine
                            + "您确定要关闭吗？", "系统提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes)
                        {
                            e.Cancel = true;
                        }
                    }
                };
                watch.Stop();
                ShowMessage("加载:" + watch.ElapsedMilliseconds + "ms");
            }
            finally
            {
                HideWaitDialog();
            }
        }
        #endregion

        private void InitBindingControls()
        {
            if (MasterBindingInfo == null) return;
            if (MasterBindingInfo.TypeIsList && MasterBindingInfo.SavableObj == null)
            {
                MasterBindingInfo.BindingSource.DataSource = MasterBindingInfo.ListType.GetConstructor(new Type[] { }).Invoke(null);
            }
            foreach (BindingInfo bindingInfo in BindingInfos.OrderBy(p => p == MasterBindingInfo))
            {
                if (bindingInfo.CriteriaBindingSource != null && bindingInfo.Criteria == null)
                {
                    var type = BindingHelper.GetListItemType(bindingInfo.CriteriaBindingSource);
                    bindingInfo.CriteriaBindingSource.DataSource = type.GetConstructor(new Type[0] { }).Invoke(null);
                    if (bindingInfo == MasterBindingInfo)
                    {
                        bindingInfo.Criteria.RecordCount = MasterMaxRecordCount;
                    }
                }
                bindingInfo.BindingSource.BindingComplete += BindingSourceBindingComplete;
                bindingInfo.BindingSource.PositionChanged += BindingSourcePositionChanged;

                if (bindingInfo.LastColumnEnterToAddnew && FormManager.BindingEditorContainers.ContainsKey(bindingInfo.BindingSource))
                {
                    var editContainers = FormManager.BindingEditorContainers[bindingInfo.BindingSource];
                    foreach (var container in editContainers)
                    {
                        if (container is GridControl)
                        {
                            var view = (container as GridControl).MainView as ColumnView;
                            if (view == null) continue;
                            view.KeyDown += (s2, a2) =>
                            {
                                if (this.EditMode && a2.KeyCode == Keys.Enter)
                                {
                                    if (view.OptionsBehavior.ReadOnly == false && view.OptionsBehavior.Editable == true)
                                    {
                                        a2.SuppressKeyPress = false;
                                        a2.Handled = true;
                                        if (view.FocusedColumn.VisibleIndex == view.VisibleColumns.Count - 1)
                                        {
                                            AddNew(bindingInfo);
                                            view.FocusedColumn = view.VisibleColumns[0];
                                            return;
                                        }
                                        for (int i = view.FocusedColumn.VisibleIndex + 1; i < view.VisibleColumns.Count; i++)
                                        {
                                            view.FocusedColumn = view.VisibleColumns[i];
                                            if (view.FocusedColumn.OptionsColumn.ReadOnly == false)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                }
                            };
                        }
                        if (container is TreeList)
                        {
                            var tree = container as TreeList;
                            tree.KeyDown += (s3, a3) =>
                                {
                                    if (a3.KeyCode == Keys.Enter && this.EditMode && tree.OptionsBehavior.Editable == true)
                                    {
                                        if ((tree.FocusedNode.NextVisibleNode == null
                                            || tree.FocusedNode.NextVisibleNode.ParentNode != tree.FocusedNode.ParentNode))
                                        {
                                            if (tree.FocusedColumn.VisibleIndex == tree.VisibleColumns.Count - 1)
                                            {
                                                var obj = AddNew(bindingInfo);
                                                tree.MoveNextVisible();
                                                tree.FocusedColumn = tree.VisibleColumns[0];
                                                a3.Handled = true;
                                                return;
                                            }
                                        }
                                    }
                                    if (a3.KeyCode == Keys.Enter || a3.KeyCode == Keys.Tab)
                                    {
                                        if (tree.FocusedColumn.VisibleIndex == tree.VisibleColumns.Count - 1)
                                        {
                                            tree.MoveNextVisible();
                                            tree.FocusedColumn = tree.VisibleColumns[0];
                                        }
                                        else
                                        {
                                            tree.FocusedColumn = tree.VisibleColumns[tree.FocusedColumn.VisibleIndex + 1];
                                        }
                                    }
                                };
                        }
                    }
                }
                if (bindingInfo.LastEditorEnterToAddnew && FormManager.BindingEditors.ContainsKey(bindingInfo.BindingSource))
                {
                    var editList = FormManager.BindingEditors[bindingInfo.BindingSource];
                    editList.LastEditor.EnterMoveNextControl = false;
                    editList.LastEditor.KeyPress += LastEditor_KeyPress;
                }
            }
        } 

        private void InitOnLoad()
        {
            if (MasterBindingInfo == null) return;
            CurrentBindingInfo = MasterBindingInfo;
            if (!IsDesignMode)
            {
                foreach (BindingInfo bindingInfo in BindingInfos)
                {
                    if (bindingInfo.IsRoot && bindingInfo != MasterBindingInfo && bindingInfo.QueryOnLoad)
                    {
                        Query(bindingInfo);
                    }
                    SetEditorsReadOnly(true, bindingInfo);
                    bindingInfo.BindingSource.BindingComplete += (sender1, e1) => { BtnSave.Enabled = MasterBindingInfo.IsDirty; };
                }
                if (MasterBindingInfo.QueryOnLoad)
                {
                    Query(MasterBindingInfo);
                    SetEditorsReadOnly(true, MasterBindingInfo);
                }
                ShowCurrentSourceInfo();
            }
        }

        void LastEditor_KeyPress(object sender, KeyPressEventArgs e)
        {
            var baseEdit = sender as BaseEdit;
            if (!EditMode || baseEdit.Properties.ReadOnly == true) return;
            if (e.KeyChar == (char)System.Windows.Forms.Keys.Enter)
            {
                CurrentBindingInfo.BindingSource.EndEdit();
                if (CurrentBindingInfo.BindingSource.Position == CurrentBindingInfo.BindingSource.List.Count - 1)
                {
                    AddNew(CurrentBindingInfo);
                }
                else
                {
                    CurrentBindingInfo.BindingSource.MoveNext();
                    FocusedToFirstControl(CurrentBindingInfo);
                }
            }
        }
    }
}